'use strict'
import {
  Model,
  DataTypes,
  InferAttributes,
  InferCreationAttributes,
  CreationOptional,
  HasManyGetAssociationsMixin,
  HasManyCountAssociationsMixin,
  HasManyCreateAssociationMixin,
} from 'sequelize'
import dayjs from 'dayjs'
import { Models } from '../type'
import Attribute from './attribute'
import sequelize from '.'

class Category extends Model<InferAttributes<Category>, InferCreationAttributes<Category>> {
  declare id: CreationOptional<number>
  declare name: string
  declare parentId: number | null
  declare createdAt: CreationOptional<Date>
  declare updatedAt: CreationOptional<Date>

  declare getAttributes: HasManyGetAssociationsMixin<Attribute>
  declare countAttributes: HasManyCountAssociationsMixin
  declare createAttribute: HasManyCreateAssociationMixin<Attribute, 'categoryId'>

  static associate(models: Models) {
    Category.hasMany(models.Category, { as: 'children', foreignKey: 'parentId', sourceKey: 'id' })
    Category.belongsTo(models.Category, { as: 'parent', foreignKey: 'parentId', targetKey: 'id' })
    Category.hasMany(models.Attribute, { as: 'attributes' })
  }
}

Category.init(
  {
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true,
    },
    name: {
      type: DataTypes.STRING,
      allowNull: false,
      validate: {
        notNull: {
          msg: '分类名称必须填写。',
        },
        notEmpty: {
          msg: '分类名称不能为空。',
        },
        len: {
          args: [2, 45],
          msg: '分类名称长度必须在2~45个字符之间。',
        },
      },
    },
    parentId: {
      type: DataTypes.INTEGER,
      // references: {
      //   model: Category,
      //   key: 'id',
      // },
      // onDelete: 'RESTRICT',
      // onUpdate: 'CASCADE',
      validate: {
        notEmpty: {
          msg: '父级分类ID不能为空。',
        },
        async isPresent(value: number | null) {
          if (value === null) {
            return
          }
          const category = await Category.findByPk(value)
          if (!category) {
            throw new Error(`ID为:${value}的父级分类不存在。`)
          }
        },
      },
    },
    createdAt: {
      type: DataTypes.DATE,
      get() {
        return this.getDataValue('createdAt')
          ? dayjs(this.getDataValue('createdAt')).format('YYYY-MM-DD HH:mm:ss')
          : null
      },
    },
    updatedAt: {
      type: DataTypes.DATE,
      get() {
        return this.getDataValue('updatedAt')
          ? dayjs(this.getDataValue('updatedAt')).format('YYYY-MM-DD HH:mm:ss')
          : null
      },
    },
  },
  {
    sequelize,
    modelName: 'Category',
  },
)

export default Category
